//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension Inspector {
    // MARK: Enums

    public enum AgentHealth: String, CustomStringConvertible, Codable, _SotoSendable {
        case healthy = "HEALTHY"
        case unhealthy = "UNHEALTHY"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum AgentHealthCode: String, CustomStringConvertible, Codable, _SotoSendable {
        case idle = "IDLE"
        case running = "RUNNING"
        case shutdown = "SHUTDOWN"
        case throttled = "THROTTLED"
        case unhealthy = "UNHEALTHY"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum AssessmentRunNotificationSnsStatusCode: String, CustomStringConvertible, Codable, _SotoSendable {
        case accessDenied = "ACCESS_DENIED"
        case internalError = "INTERNAL_ERROR"
        case success = "SUCCESS"
        case topicDoesNotExist = "TOPIC_DOES_NOT_EXIST"
        public var description: String { return self.rawValue }
    }

    public enum AssessmentRunState: String, CustomStringConvertible, Codable, _SotoSendable {
        case canceled = "CANCELED"
        case collectingData = "COLLECTING_DATA"
        case completed = "COMPLETED"
        case completedWithErrors = "COMPLETED_WITH_ERRORS"
        case created = "CREATED"
        case dataCollected = "DATA_COLLECTED"
        case error = "ERROR"
        case evaluatingRules = "EVALUATING_RULES"
        case failed = "FAILED"
        case startDataCollectionInProgress = "START_DATA_COLLECTION_IN_PROGRESS"
        case startDataCollectionPending = "START_DATA_COLLECTION_PENDING"
        case startEvaluatingRulesPending = "START_EVALUATING_RULES_PENDING"
        case stopDataCollectionPending = "STOP_DATA_COLLECTION_PENDING"
        public var description: String { return self.rawValue }
    }

    public enum AssetType: String, CustomStringConvertible, Codable, _SotoSendable {
        case ec2Instance = "ec2-instance"
        public var description: String { return self.rawValue }
    }

    public enum FailedItemErrorCode: String, CustomStringConvertible, Codable, _SotoSendable {
        case accessDenied = "ACCESS_DENIED"
        case duplicateArn = "DUPLICATE_ARN"
        case internalError = "INTERNAL_ERROR"
        case invalidArn = "INVALID_ARN"
        case itemDoesNotExist = "ITEM_DOES_NOT_EXIST"
        case limitExceeded = "LIMIT_EXCEEDED"
        public var description: String { return self.rawValue }
    }

    public enum InspectorEvent: String, CustomStringConvertible, Codable, _SotoSendable {
        case assessmentRunCompleted = "ASSESSMENT_RUN_COMPLETED"
        case assessmentRunStarted = "ASSESSMENT_RUN_STARTED"
        case assessmentRunStateChanged = "ASSESSMENT_RUN_STATE_CHANGED"
        case findingReported = "FINDING_REPORTED"
        case other = "OTHER"
        public var description: String { return self.rawValue }
    }

    public enum Locale: String, CustomStringConvertible, Codable, _SotoSendable {
        case enUs = "EN_US"
        public var description: String { return self.rawValue }
    }

    public enum PreviewStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case workInProgress = "WORK_IN_PROGRESS"
        public var description: String { return self.rawValue }
    }

    public enum ReportFileFormat: String, CustomStringConvertible, Codable, _SotoSendable {
        case html = "HTML"
        case pdf = "PDF"
        public var description: String { return self.rawValue }
    }

    public enum ReportStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case failed = "FAILED"
        case workInProgress = "WORK_IN_PROGRESS"
        public var description: String { return self.rawValue }
    }

    public enum ReportType: String, CustomStringConvertible, Codable, _SotoSendable {
        case finding = "FINDING"
        case full = "FULL"
        public var description: String { return self.rawValue }
    }

    public enum ScopeType: String, CustomStringConvertible, Codable, _SotoSendable {
        case instanceId = "INSTANCE_ID"
        case rulesPackageArn = "RULES_PACKAGE_ARN"
        public var description: String { return self.rawValue }
    }

    public enum Severity: String, CustomStringConvertible, Codable, _SotoSendable {
        case high = "High"
        case informational = "Informational"
        case low = "Low"
        case medium = "Medium"
        case undefined = "Undefined"
        public var description: String { return self.rawValue }
    }

    public enum StopAction: String, CustomStringConvertible, Codable, _SotoSendable {
        case skipEvaluation = "SKIP_EVALUATION"
        case startEvaluation = "START_EVALUATION"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AddAttributesToFindingsRequest: AWSEncodableShape {
        /// The array of attributes that you want to assign to specified findings.
        public let attributes: [Attribute]
        /// The ARNs that specify the findings that you want to assign attributes to.
        public let findingArns: [String]

        public init(attributes: [Attribute], findingArns: [String]) {
            self.attributes = attributes
            self.findingArns = findingArns
        }

        public func validate(name: String) throws {
            try self.attributes.forEach {
                try $0.validate(name: "\(name).attributes[]")
            }
            try self.validate(self.attributes, name: "attributes", parent: name, max: 10)
            try self.findingArns.forEach {
                try validate($0, name: "findingArns[]", parent: name, max: 300)
                try validate($0, name: "findingArns[]", parent: name, min: 1)
            }
            try self.validate(self.findingArns, name: "findingArns", parent: name, max: 10)
            try self.validate(self.findingArns, name: "findingArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case attributes
            case findingArns
        }
    }

    public struct AddAttributesToFindingsResponse: AWSDecodableShape {
        /// Attribute details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(failedItems: [String: FailedItemDetails]) {
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case failedItems
        }
    }

    public struct AgentFilter: AWSEncodableShape {
        /// The detailed health state of the agent. Values can be set to IDLE, RUNNING, SHUTDOWN, UNHEALTHY, THROTTLED, and UNKNOWN.
        public let agentHealthCodes: [AgentHealthCode]
        /// The current health state of the agent. Values can be set to HEALTHY or UNHEALTHY.
        public let agentHealths: [AgentHealth]

        public init(agentHealthCodes: [AgentHealthCode], agentHealths: [AgentHealth]) {
            self.agentHealthCodes = agentHealthCodes
            self.agentHealths = agentHealths
        }

        public func validate(name: String) throws {
            try self.validate(self.agentHealthCodes, name: "agentHealthCodes", parent: name, max: 10)
            try self.validate(self.agentHealths, name: "agentHealths", parent: name, max: 10)
        }

        private enum CodingKeys: String, CodingKey {
            case agentHealthCodes
            case agentHealths
        }
    }

    public struct AgentPreview: AWSDecodableShape {
        /// The health status of the Amazon Inspector Agent.
        public let agentHealth: AgentHealth?
        /// The ID of the EC2 instance where the agent is installed.
        public let agentId: String
        /// The version of the Amazon Inspector Agent.
        public let agentVersion: String?
        /// The Auto Scaling group for the EC2 instance where the agent is installed.
        public let autoScalingGroup: String?
        /// The hostname of the EC2 instance on which the Amazon Inspector Agent is installed.
        public let hostname: String?
        /// The IP address of the EC2 instance on which the Amazon Inspector Agent is installed.
        public let ipv4Address: String?
        /// The kernel version of the operating system running on the EC2 instance on which the Amazon Inspector Agent is installed.
        public let kernelVersion: String?
        /// The operating system running on the EC2 instance on which the Amazon Inspector Agent is installed.
        public let operatingSystem: String?

        public init(agentHealth: AgentHealth? = nil, agentId: String, agentVersion: String? = nil, autoScalingGroup: String? = nil, hostname: String? = nil, ipv4Address: String? = nil, kernelVersion: String? = nil, operatingSystem: String? = nil) {
            self.agentHealth = agentHealth
            self.agentId = agentId
            self.agentVersion = agentVersion
            self.autoScalingGroup = autoScalingGroup
            self.hostname = hostname
            self.ipv4Address = ipv4Address
            self.kernelVersion = kernelVersion
            self.operatingSystem = operatingSystem
        }

        private enum CodingKeys: String, CodingKey {
            case agentHealth
            case agentId
            case agentVersion
            case autoScalingGroup
            case hostname
            case ipv4Address
            case kernelVersion
            case operatingSystem
        }
    }

    public struct AssessmentRun: AWSDecodableShape {
        /// The ARN of the assessment run.
        public let arn: String
        /// The ARN of the assessment template that is associated with the assessment run.
        public let assessmentTemplateArn: String
        /// The assessment run completion time that corresponds to the rules packages evaluation completion time or failure.
        public let completedAt: Date?
        /// The time when StartAssessmentRun was called.
        public let createdAt: Date
        /// A Boolean value (true or false) that specifies whether the process of collecting data from the agents is completed.
        public let dataCollected: Bool
        /// The duration of the assessment run.
        public let durationInSeconds: Int
        /// Provides a total count of generated findings per severity.
        public let findingCounts: [Severity: Int]
        /// The auto-generated name for the assessment run.
        public let name: String
        /// A list of notifications for the event subscriptions. A notification about a particular generated finding is added to this list only once.
        public let notifications: [AssessmentRunNotification]
        /// The rules packages selected for the assessment run.
        public let rulesPackageArns: [String]
        /// The time when StartAssessmentRun was called.
        public let startedAt: Date?
        /// The state of the assessment run.
        public let state: AssessmentRunState
        /// The last time when the assessment run's state changed.
        public let stateChangedAt: Date
        /// A list of the assessment run state changes.
        public let stateChanges: [AssessmentRunStateChange]
        /// The user-defined attributes that are assigned to every generated finding.
        public let userAttributesForFindings: [Attribute]

        public init(arn: String, assessmentTemplateArn: String, completedAt: Date? = nil, createdAt: Date, dataCollected: Bool, durationInSeconds: Int, findingCounts: [Severity: Int], name: String, notifications: [AssessmentRunNotification], rulesPackageArns: [String], startedAt: Date? = nil, state: AssessmentRunState, stateChangedAt: Date, stateChanges: [AssessmentRunStateChange], userAttributesForFindings: [Attribute]) {
            self.arn = arn
            self.assessmentTemplateArn = assessmentTemplateArn
            self.completedAt = completedAt
            self.createdAt = createdAt
            self.dataCollected = dataCollected
            self.durationInSeconds = durationInSeconds
            self.findingCounts = findingCounts
            self.name = name
            self.notifications = notifications
            self.rulesPackageArns = rulesPackageArns
            self.startedAt = startedAt
            self.state = state
            self.stateChangedAt = stateChangedAt
            self.stateChanges = stateChanges
            self.userAttributesForFindings = userAttributesForFindings
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case assessmentTemplateArn
            case completedAt
            case createdAt
            case dataCollected
            case durationInSeconds
            case findingCounts
            case name
            case notifications
            case rulesPackageArns
            case startedAt
            case state
            case stateChangedAt
            case stateChanges
            case userAttributesForFindings
        }
    }

    public struct AssessmentRunAgent: AWSDecodableShape {
        /// The current health state of the agent.
        public let agentHealth: AgentHealth
        /// The detailed health state of the agent.
        public let agentHealthCode: AgentHealthCode
        /// The description for the agent health code.
        public let agentHealthDetails: String?
        /// The AWS account of the EC2 instance where the agent is installed.
        public let agentId: String
        /// The ARN of the assessment run that is associated with the agent.
        public let assessmentRunArn: String
        /// The Auto Scaling group of the EC2 instance that is specified by the agent ID.
        public let autoScalingGroup: String?
        /// The Amazon Inspector application data metrics that are collected by the agent.
        public let telemetryMetadata: [TelemetryMetadata]

        public init(agentHealth: AgentHealth, agentHealthCode: AgentHealthCode, agentHealthDetails: String? = nil, agentId: String, assessmentRunArn: String, autoScalingGroup: String? = nil, telemetryMetadata: [TelemetryMetadata]) {
            self.agentHealth = agentHealth
            self.agentHealthCode = agentHealthCode
            self.agentHealthDetails = agentHealthDetails
            self.agentId = agentId
            self.assessmentRunArn = assessmentRunArn
            self.autoScalingGroup = autoScalingGroup
            self.telemetryMetadata = telemetryMetadata
        }

        private enum CodingKeys: String, CodingKey {
            case agentHealth
            case agentHealthCode
            case agentHealthDetails
            case agentId
            case assessmentRunArn
            case autoScalingGroup
            case telemetryMetadata
        }
    }

    public struct AssessmentRunFilter: AWSEncodableShape {
        /// For a record to match a filter, the value that is specified for this data type property must inclusively match any value between the specified minimum and maximum values of the completedAt property of the AssessmentRun data type.
        public let completionTimeRange: TimestampRange?
        /// For a record to match a filter, the value that is specified for this data type property must inclusively match any value between the specified minimum and maximum values of the durationInSeconds property of the AssessmentRun data type.
        public let durationRange: DurationRange?
        /// For a record to match a filter, an explicit value or a string containing a wildcard that is specified for this data type property must match the value of the assessmentRunName property of the AssessmentRun data type.
        public let namePattern: String?
        /// For a record to match a filter, the value that is specified for this data type property must be contained in the list of values of the rulesPackages property of the AssessmentRun data type.
        public let rulesPackageArns: [String]?
        /// For a record to match a filter, the value that is specified for this data type property must inclusively match any value between the specified minimum and maximum values of the startTime property of the AssessmentRun data type.
        public let startTimeRange: TimestampRange?
        /// For a record to match a filter, the value that is specified for this data type property must match the stateChangedAt property of the AssessmentRun data type.
        public let stateChangeTimeRange: TimestampRange?
        /// For a record to match a filter, one of the values specified for this data type property must be the exact match of the value of the assessmentRunState property of the AssessmentRun data type.
        public let states: [AssessmentRunState]?

        public init(completionTimeRange: TimestampRange? = nil, durationRange: DurationRange? = nil, namePattern: String? = nil, rulesPackageArns: [String]? = nil, startTimeRange: TimestampRange? = nil, stateChangeTimeRange: TimestampRange? = nil, states: [AssessmentRunState]? = nil) {
            self.completionTimeRange = completionTimeRange
            self.durationRange = durationRange
            self.namePattern = namePattern
            self.rulesPackageArns = rulesPackageArns
            self.startTimeRange = startTimeRange
            self.stateChangeTimeRange = stateChangeTimeRange
            self.states = states
        }

        public func validate(name: String) throws {
            try self.durationRange?.validate(name: "\(name).durationRange")
            try self.validate(self.namePattern, name: "namePattern", parent: name, max: 140)
            try self.validate(self.namePattern, name: "namePattern", parent: name, min: 1)
            try self.rulesPackageArns?.forEach {
                try validate($0, name: "rulesPackageArns[]", parent: name, max: 300)
                try validate($0, name: "rulesPackageArns[]", parent: name, min: 1)
            }
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, max: 50)
            try self.validate(self.states, name: "states", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case completionTimeRange
            case durationRange
            case namePattern
            case rulesPackageArns
            case startTimeRange
            case stateChangeTimeRange
            case states
        }
    }

    public struct AssessmentRunNotification: AWSDecodableShape {
        /// The date of the notification.
        public let date: Date
        /// The Boolean value that specifies whether the notification represents an error.
        public let error: Bool
        /// The event for which a notification is sent.
        public let event: InspectorEvent
        /// The message included in the notification.
        public let message: String?
        /// The status code of the SNS notification.
        public let snsPublishStatusCode: AssessmentRunNotificationSnsStatusCode?
        /// The SNS topic to which the SNS notification is sent.
        public let snsTopicArn: String?

        public init(date: Date, error: Bool, event: InspectorEvent, message: String? = nil, snsPublishStatusCode: AssessmentRunNotificationSnsStatusCode? = nil, snsTopicArn: String? = nil) {
            self.date = date
            self.error = error
            self.event = event
            self.message = message
            self.snsPublishStatusCode = snsPublishStatusCode
            self.snsTopicArn = snsTopicArn
        }

        private enum CodingKeys: String, CodingKey {
            case date
            case error
            case event
            case message
            case snsPublishStatusCode
            case snsTopicArn
        }
    }

    public struct AssessmentRunStateChange: AWSDecodableShape {
        /// The assessment run state.
        public let state: AssessmentRunState
        /// The last time the assessment run state changed.
        public let stateChangedAt: Date

        public init(state: AssessmentRunState, stateChangedAt: Date) {
            self.state = state
            self.stateChangedAt = stateChangedAt
        }

        private enum CodingKeys: String, CodingKey {
            case state
            case stateChangedAt
        }
    }

    public struct AssessmentTarget: AWSDecodableShape {
        /// The ARN that specifies the Amazon Inspector assessment target.
        public let arn: String
        /// The time at which the assessment target is created.
        public let createdAt: Date
        /// The name of the Amazon Inspector assessment target.
        public let name: String
        /// The ARN that specifies the resource group that is associated with the assessment target.
        public let resourceGroupArn: String?
        /// The time at which UpdateAssessmentTarget is called.
        public let updatedAt: Date

        public init(arn: String, createdAt: Date, name: String, resourceGroupArn: String? = nil, updatedAt: Date) {
            self.arn = arn
            self.createdAt = createdAt
            self.name = name
            self.resourceGroupArn = resourceGroupArn
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdAt
            case name
            case resourceGroupArn
            case updatedAt
        }
    }

    public struct AssessmentTargetFilter: AWSEncodableShape {
        /// For a record to match a filter, an explicit value or a string that contains a wildcard that is specified for this data type property must match the value of the assessmentTargetName property of the AssessmentTarget data type.
        public let assessmentTargetNamePattern: String?

        public init(assessmentTargetNamePattern: String? = nil) {
            self.assessmentTargetNamePattern = assessmentTargetNamePattern
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTargetNamePattern, name: "assessmentTargetNamePattern", parent: name, max: 140)
            try self.validate(self.assessmentTargetNamePattern, name: "assessmentTargetNamePattern", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetNamePattern
        }
    }

    public struct AssessmentTemplate: AWSDecodableShape {
        /// The ARN of the assessment template.
        public let arn: String
        /// The number of existing assessment runs associated with this assessment template. This value can be zero or a positive integer.
        public let assessmentRunCount: Int
        /// The ARN of the assessment target that corresponds to this assessment template.
        public let assessmentTargetArn: String
        /// The time at which the assessment template is created.
        public let createdAt: Date
        /// The duration in seconds specified for this assessment template. The default value is 3600 seconds (one hour). The maximum value is 86400 seconds (one day).
        public let durationInSeconds: Int
        /// The Amazon Resource Name (ARN) of the most recent assessment run associated with this assessment template. This value exists only when the value of assessmentRunCount is greaterpa than zero.
        public let lastAssessmentRunArn: String?
        /// The name of the assessment template.
        public let name: String
        /// The rules packages that are specified for this assessment template.
        public let rulesPackageArns: [String]
        /// The user-defined attributes that are assigned to every generated finding from the assessment run that uses this assessment template.
        public let userAttributesForFindings: [Attribute]

        public init(arn: String, assessmentRunCount: Int, assessmentTargetArn: String, createdAt: Date, durationInSeconds: Int, lastAssessmentRunArn: String? = nil, name: String, rulesPackageArns: [String], userAttributesForFindings: [Attribute]) {
            self.arn = arn
            self.assessmentRunCount = assessmentRunCount
            self.assessmentTargetArn = assessmentTargetArn
            self.createdAt = createdAt
            self.durationInSeconds = durationInSeconds
            self.lastAssessmentRunArn = lastAssessmentRunArn
            self.name = name
            self.rulesPackageArns = rulesPackageArns
            self.userAttributesForFindings = userAttributesForFindings
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case assessmentRunCount
            case assessmentTargetArn
            case createdAt
            case durationInSeconds
            case lastAssessmentRunArn
            case name
            case rulesPackageArns
            case userAttributesForFindings
        }
    }

    public struct AssessmentTemplateFilter: AWSEncodableShape {
        /// For a record to match a filter, the value specified for this data type property must inclusively match any value between the specified minimum and maximum values of the durationInSeconds property of the AssessmentTemplate data type.
        public let durationRange: DurationRange?
        /// For a record to match a filter, an explicit value or a string that contains a wildcard that is specified for this data type property must match the value of the assessmentTemplateName property of the AssessmentTemplate data type.
        public let namePattern: String?
        /// For a record to match a filter, the values that are specified for this data type property must be contained in the list of values of the rulesPackageArns property of the AssessmentTemplate data type.
        public let rulesPackageArns: [String]?

        public init(durationRange: DurationRange? = nil, namePattern: String? = nil, rulesPackageArns: [String]? = nil) {
            self.durationRange = durationRange
            self.namePattern = namePattern
            self.rulesPackageArns = rulesPackageArns
        }

        public func validate(name: String) throws {
            try self.durationRange?.validate(name: "\(name).durationRange")
            try self.validate(self.namePattern, name: "namePattern", parent: name, max: 140)
            try self.validate(self.namePattern, name: "namePattern", parent: name, min: 1)
            try self.rulesPackageArns?.forEach {
                try validate($0, name: "rulesPackageArns[]", parent: name, max: 300)
                try validate($0, name: "rulesPackageArns[]", parent: name, min: 1)
            }
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case durationRange
            case namePattern
            case rulesPackageArns
        }
    }

    public struct AssetAttributes: AWSDecodableShape {
        /// The ID of the agent that is installed on the EC2 instance where the finding is generated.
        public let agentId: String?
        /// The ID of the Amazon Machine Image (AMI) that is installed on the EC2 instance where the finding is generated.
        public let amiId: String?
        /// The Auto Scaling group of the EC2 instance where the finding is generated.
        public let autoScalingGroup: String?
        /// The hostname of the EC2 instance where the finding is generated.
        public let hostname: String?
        /// The list of IP v4 addresses of the EC2 instance where the finding is generated.
        public let ipv4Addresses: [String]?
        /// An array of the network interfaces interacting with the EC2 instance where the finding is generated.
        public let networkInterfaces: [NetworkInterface]?
        /// The schema version of this data type.
        public let schemaVersion: Int
        /// The tags related to the EC2 instance where the finding is generated.
        public let tags: [Tag]?

        public init(agentId: String? = nil, amiId: String? = nil, autoScalingGroup: String? = nil, hostname: String? = nil, ipv4Addresses: [String]? = nil, networkInterfaces: [NetworkInterface]? = nil, schemaVersion: Int, tags: [Tag]? = nil) {
            self.agentId = agentId
            self.amiId = amiId
            self.autoScalingGroup = autoScalingGroup
            self.hostname = hostname
            self.ipv4Addresses = ipv4Addresses
            self.networkInterfaces = networkInterfaces
            self.schemaVersion = schemaVersion
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case agentId
            case amiId
            case autoScalingGroup
            case hostname
            case ipv4Addresses
            case networkInterfaces
            case schemaVersion
            case tags
        }
    }

    public struct Attribute: AWSEncodableShape & AWSDecodableShape {
        /// The attribute key.
        public let key: String
        /// The value assigned to the attribute key.
        public let value: String?

        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct CreateAssessmentTargetRequest: AWSEncodableShape {
        /// The user-defined name that identifies the assessment target that you want to create. The name must be unique within the AWS account.
        public let assessmentTargetName: String
        /// The ARN that specifies the resource group that is used to create the assessment target. If resourceGroupArn is not specified, all EC2 instances in the current AWS account and region are included in the assessment target.
        public let resourceGroupArn: String?

        public init(assessmentTargetName: String, resourceGroupArn: String? = nil) {
            self.assessmentTargetName = assessmentTargetName
            self.resourceGroupArn = resourceGroupArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTargetName, name: "assessmentTargetName", parent: name, max: 140)
            try self.validate(self.assessmentTargetName, name: "assessmentTargetName", parent: name, min: 1)
            try self.validate(self.resourceGroupArn, name: "resourceGroupArn", parent: name, max: 300)
            try self.validate(self.resourceGroupArn, name: "resourceGroupArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetName
            case resourceGroupArn
        }
    }

    public struct CreateAssessmentTargetResponse: AWSDecodableShape {
        /// The ARN that specifies the assessment target that is created.
        public let assessmentTargetArn: String

        public init(assessmentTargetArn: String) {
            self.assessmentTargetArn = assessmentTargetArn
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArn
        }
    }

    public struct CreateAssessmentTemplateRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment target for which you want to create the assessment template.
        public let assessmentTargetArn: String
        /// The user-defined name that identifies the assessment template that you want to create. You can create several assessment templates for an assessment target. The names of the assessment templates that correspond to a particular assessment target must be unique.
        public let assessmentTemplateName: String
        /// The duration of the assessment run in seconds.
        public let durationInSeconds: Int
        /// The ARNs that specify the rules packages that you want to attach to the assessment template.
        public let rulesPackageArns: [String]
        /// The user-defined attributes that are assigned to every finding that is generated by the assessment run that uses this assessment template. An attribute is a key and value pair (an Attribute object). Within an assessment template, each key must be unique.
        public let userAttributesForFindings: [Attribute]?

        public init(assessmentTargetArn: String, assessmentTemplateName: String, durationInSeconds: Int, rulesPackageArns: [String], userAttributesForFindings: [Attribute]? = nil) {
            self.assessmentTargetArn = assessmentTargetArn
            self.assessmentTemplateName = assessmentTemplateName
            self.durationInSeconds = durationInSeconds
            self.rulesPackageArns = rulesPackageArns
            self.userAttributesForFindings = userAttributesForFindings
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, max: 300)
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, min: 1)
            try self.validate(self.assessmentTemplateName, name: "assessmentTemplateName", parent: name, max: 140)
            try self.validate(self.assessmentTemplateName, name: "assessmentTemplateName", parent: name, min: 1)
            try self.validate(self.durationInSeconds, name: "durationInSeconds", parent: name, max: 86400)
            try self.validate(self.durationInSeconds, name: "durationInSeconds", parent: name, min: 180)
            try self.rulesPackageArns.forEach {
                try validate($0, name: "rulesPackageArns[]", parent: name, max: 300)
                try validate($0, name: "rulesPackageArns[]", parent: name, min: 1)
            }
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, max: 50)
            try self.userAttributesForFindings?.forEach {
                try $0.validate(name: "\(name).userAttributesForFindings[]")
            }
            try self.validate(self.userAttributesForFindings, name: "userAttributesForFindings", parent: name, max: 10)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArn
            case assessmentTemplateName
            case durationInSeconds
            case rulesPackageArns
            case userAttributesForFindings
        }
    }

    public struct CreateAssessmentTemplateResponse: AWSDecodableShape {
        /// The ARN that specifies the assessment template that is created.
        public let assessmentTemplateArn: String

        public init(assessmentTemplateArn: String) {
            self.assessmentTemplateArn = assessmentTemplateArn
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArn
        }
    }

    public struct CreateExclusionsPreviewRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment template for which you want to create an exclusions preview.
        public let assessmentTemplateArn: String

        public init(assessmentTemplateArn: String) {
            self.assessmentTemplateArn = assessmentTemplateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, max: 300)
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArn
        }
    }

    public struct CreateExclusionsPreviewResponse: AWSDecodableShape {
        /// Specifies the unique identifier of the requested exclusions preview. You can use the unique identifier to retrieve the exclusions preview when running the GetExclusionsPreview API.
        public let previewToken: String

        public init(previewToken: String) {
            self.previewToken = previewToken
        }

        private enum CodingKeys: String, CodingKey {
            case previewToken
        }
    }

    public struct CreateResourceGroupRequest: AWSEncodableShape {
        /// A collection of keys and an array of possible values, '[{"key":"key1","values":["Value1","Value2"]},{"key":"Key2","values":["Value3"]}]'. For example,'[{"key":"Name","values":["TestEC2Instance"]}]'.
        public let resourceGroupTags: [ResourceGroupTag]

        public init(resourceGroupTags: [ResourceGroupTag]) {
            self.resourceGroupTags = resourceGroupTags
        }

        public func validate(name: String) throws {
            try self.resourceGroupTags.forEach {
                try $0.validate(name: "\(name).resourceGroupTags[]")
            }
            try self.validate(self.resourceGroupTags, name: "resourceGroupTags", parent: name, max: 10)
            try self.validate(self.resourceGroupTags, name: "resourceGroupTags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceGroupTags
        }
    }

    public struct CreateResourceGroupResponse: AWSDecodableShape {
        /// The ARN that specifies the resource group that is created.
        public let resourceGroupArn: String

        public init(resourceGroupArn: String) {
            self.resourceGroupArn = resourceGroupArn
        }

        private enum CodingKeys: String, CodingKey {
            case resourceGroupArn
        }
    }

    public struct DeleteAssessmentRunRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment run that you want to delete.
        public let assessmentRunArn: String

        public init(assessmentRunArn: String) {
            self.assessmentRunArn = assessmentRunArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
        }
    }

    public struct DeleteAssessmentTargetRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment target that you want to delete.
        public let assessmentTargetArn: String

        public init(assessmentTargetArn: String) {
            self.assessmentTargetArn = assessmentTargetArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, max: 300)
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArn
        }
    }

    public struct DeleteAssessmentTemplateRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment template that you want to delete.
        public let assessmentTemplateArn: String

        public init(assessmentTemplateArn: String) {
            self.assessmentTemplateArn = assessmentTemplateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, max: 300)
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArn
        }
    }

    public struct DescribeAssessmentRunsRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment run that you want to describe.
        public let assessmentRunArns: [String]

        public init(assessmentRunArns: [String]) {
            self.assessmentRunArns = assessmentRunArns
        }

        public func validate(name: String) throws {
            try self.assessmentRunArns.forEach {
                try validate($0, name: "assessmentRunArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentRunArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentRunArns, name: "assessmentRunArns", parent: name, max: 10)
            try self.validate(self.assessmentRunArns, name: "assessmentRunArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArns
        }
    }

    public struct DescribeAssessmentRunsResponse: AWSDecodableShape {
        /// Information about the assessment run.
        public let assessmentRuns: [AssessmentRun]
        /// Assessment run details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(assessmentRuns: [AssessmentRun], failedItems: [String: FailedItemDetails]) {
            self.assessmentRuns = assessmentRuns
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRuns
            case failedItems
        }
    }

    public struct DescribeAssessmentTargetsRequest: AWSEncodableShape {
        /// The ARNs that specifies the assessment targets that you want to describe.
        public let assessmentTargetArns: [String]

        public init(assessmentTargetArns: [String]) {
            self.assessmentTargetArns = assessmentTargetArns
        }

        public func validate(name: String) throws {
            try self.assessmentTargetArns.forEach {
                try validate($0, name: "assessmentTargetArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentTargetArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentTargetArns, name: "assessmentTargetArns", parent: name, max: 10)
            try self.validate(self.assessmentTargetArns, name: "assessmentTargetArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArns
        }
    }

    public struct DescribeAssessmentTargetsResponse: AWSDecodableShape {
        /// Information about the assessment targets.
        public let assessmentTargets: [AssessmentTarget]
        /// Assessment target details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(assessmentTargets: [AssessmentTarget], failedItems: [String: FailedItemDetails]) {
            self.assessmentTargets = assessmentTargets
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargets
            case failedItems
        }
    }

    public struct DescribeAssessmentTemplatesRequest: AWSEncodableShape {
        public let assessmentTemplateArns: [String]

        public init(assessmentTemplateArns: [String]) {
            self.assessmentTemplateArns = assessmentTemplateArns
        }

        public func validate(name: String) throws {
            try self.assessmentTemplateArns.forEach {
                try validate($0, name: "assessmentTemplateArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentTemplateArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentTemplateArns, name: "assessmentTemplateArns", parent: name, max: 10)
            try self.validate(self.assessmentTemplateArns, name: "assessmentTemplateArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArns
        }
    }

    public struct DescribeAssessmentTemplatesResponse: AWSDecodableShape {
        /// Information about the assessment templates.
        public let assessmentTemplates: [AssessmentTemplate]
        /// Assessment template details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(assessmentTemplates: [AssessmentTemplate], failedItems: [String: FailedItemDetails]) {
            self.assessmentTemplates = assessmentTemplates
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplates
            case failedItems
        }
    }

    public struct DescribeCrossAccountAccessRoleResponse: AWSDecodableShape {
        /// The date when the cross-account access role was registered.
        public let registeredAt: Date
        /// The ARN that specifies the IAM role that Amazon Inspector uses to access your AWS account.
        public let roleArn: String
        /// A Boolean value that specifies whether the IAM role has the necessary policies attached to enable Amazon Inspector to access your AWS account.
        public let valid: Bool

        public init(registeredAt: Date, roleArn: String, valid: Bool) {
            self.registeredAt = registeredAt
            self.roleArn = roleArn
            self.valid = valid
        }

        private enum CodingKeys: String, CodingKey {
            case registeredAt
            case roleArn
            case valid
        }
    }

    public struct DescribeExclusionsRequest: AWSEncodableShape {
        /// The list of ARNs that specify the exclusions that you want to describe.
        public let exclusionArns: [String]
        /// The locale into which you want to translate the exclusion's title, description, and recommendation.
        public let locale: Locale?

        public init(exclusionArns: [String], locale: Locale? = nil) {
            self.exclusionArns = exclusionArns
            self.locale = locale
        }

        public func validate(name: String) throws {
            try self.exclusionArns.forEach {
                try validate($0, name: "exclusionArns[]", parent: name, max: 300)
                try validate($0, name: "exclusionArns[]", parent: name, min: 1)
            }
            try self.validate(self.exclusionArns, name: "exclusionArns", parent: name, max: 100)
            try self.validate(self.exclusionArns, name: "exclusionArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case exclusionArns
            case locale
        }
    }

    public struct DescribeExclusionsResponse: AWSDecodableShape {
        /// Information about the exclusions.
        public let exclusions: [String: Exclusion]
        /// Exclusion details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(exclusions: [String: Exclusion], failedItems: [String: FailedItemDetails]) {
            self.exclusions = exclusions
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case exclusions
            case failedItems
        }
    }

    public struct DescribeFindingsRequest: AWSEncodableShape {
        /// The ARN that specifies the finding that you want to describe.
        public let findingArns: [String]
        /// The locale into which you want to translate a finding description, recommendation, and the short description that identifies the finding.
        public let locale: Locale?

        public init(findingArns: [String], locale: Locale? = nil) {
            self.findingArns = findingArns
            self.locale = locale
        }

        public func validate(name: String) throws {
            try self.findingArns.forEach {
                try validate($0, name: "findingArns[]", parent: name, max: 300)
                try validate($0, name: "findingArns[]", parent: name, min: 1)
            }
            try self.validate(self.findingArns, name: "findingArns", parent: name, max: 10)
            try self.validate(self.findingArns, name: "findingArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case findingArns
            case locale
        }
    }

    public struct DescribeFindingsResponse: AWSDecodableShape {
        /// Finding details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]
        /// Information about the finding.
        public let findings: [Finding]

        public init(failedItems: [String: FailedItemDetails], findings: [Finding]) {
            self.failedItems = failedItems
            self.findings = findings
        }

        private enum CodingKeys: String, CodingKey {
            case failedItems
            case findings
        }
    }

    public struct DescribeResourceGroupsRequest: AWSEncodableShape {
        /// The ARN that specifies the resource group that you want to describe.
        public let resourceGroupArns: [String]

        public init(resourceGroupArns: [String]) {
            self.resourceGroupArns = resourceGroupArns
        }

        public func validate(name: String) throws {
            try self.resourceGroupArns.forEach {
                try validate($0, name: "resourceGroupArns[]", parent: name, max: 300)
                try validate($0, name: "resourceGroupArns[]", parent: name, min: 1)
            }
            try self.validate(self.resourceGroupArns, name: "resourceGroupArns", parent: name, max: 10)
            try self.validate(self.resourceGroupArns, name: "resourceGroupArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceGroupArns
        }
    }

    public struct DescribeResourceGroupsResponse: AWSDecodableShape {
        /// Resource group details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]
        /// Information about a resource group.
        public let resourceGroups: [ResourceGroup]

        public init(failedItems: [String: FailedItemDetails], resourceGroups: [ResourceGroup]) {
            self.failedItems = failedItems
            self.resourceGroups = resourceGroups
        }

        private enum CodingKeys: String, CodingKey {
            case failedItems
            case resourceGroups
        }
    }

    public struct DescribeRulesPackagesRequest: AWSEncodableShape {
        /// The locale that you want to translate a rules package description into.
        public let locale: Locale?
        /// The ARN that specifies the rules package that you want to describe.
        public let rulesPackageArns: [String]

        public init(locale: Locale? = nil, rulesPackageArns: [String]) {
            self.locale = locale
            self.rulesPackageArns = rulesPackageArns
        }

        public func validate(name: String) throws {
            try self.rulesPackageArns.forEach {
                try validate($0, name: "rulesPackageArns[]", parent: name, max: 300)
                try validate($0, name: "rulesPackageArns[]", parent: name, min: 1)
            }
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, max: 10)
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case locale
            case rulesPackageArns
        }
    }

    public struct DescribeRulesPackagesResponse: AWSDecodableShape {
        /// Rules package details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]
        /// Information about the rules package.
        public let rulesPackages: [RulesPackage]

        public init(failedItems: [String: FailedItemDetails], rulesPackages: [RulesPackage]) {
            self.failedItems = failedItems
            self.rulesPackages = rulesPackages
        }

        private enum CodingKeys: String, CodingKey {
            case failedItems
            case rulesPackages
        }
    }

    public struct DurationRange: AWSEncodableShape {
        /// The maximum value of the duration range. Must be less than or equal to 604800 seconds (1 week).
        public let maxSeconds: Int?
        /// The minimum value of the duration range. Must be greater than zero.
        public let minSeconds: Int?

        public init(maxSeconds: Int? = nil, minSeconds: Int? = nil) {
            self.maxSeconds = maxSeconds
            self.minSeconds = minSeconds
        }

        public func validate(name: String) throws {
            try self.validate(self.maxSeconds, name: "maxSeconds", parent: name, max: 86400)
            try self.validate(self.maxSeconds, name: "maxSeconds", parent: name, min: 180)
            try self.validate(self.minSeconds, name: "minSeconds", parent: name, max: 86400)
            try self.validate(self.minSeconds, name: "minSeconds", parent: name, min: 180)
        }

        private enum CodingKeys: String, CodingKey {
            case maxSeconds
            case minSeconds
        }
    }

    public struct EventSubscription: AWSDecodableShape {
        /// The event for which Amazon Simple Notification Service (SNS) notifications are sent.
        public let event: InspectorEvent
        /// The time at which SubscribeToEvent is called.
        public let subscribedAt: Date

        public init(event: InspectorEvent, subscribedAt: Date) {
            self.event = event
            self.subscribedAt = subscribedAt
        }

        private enum CodingKeys: String, CodingKey {
            case event
            case subscribedAt
        }
    }

    public struct Exclusion: AWSDecodableShape {
        /// The ARN that specifies the exclusion.
        public let arn: String
        /// The system-defined attributes for the exclusion.
        public let attributes: [Attribute]?
        /// The description of the exclusion.
        public let description: String
        /// The recommendation for the exclusion.
        public let recommendation: String
        /// The AWS resources for which the exclusion pertains.
        public let scopes: [Scope]
        /// The name of the exclusion.
        public let title: String

        public init(arn: String, attributes: [Attribute]? = nil, description: String, recommendation: String, scopes: [Scope], title: String) {
            self.arn = arn
            self.attributes = attributes
            self.description = description
            self.recommendation = recommendation
            self.scopes = scopes
            self.title = title
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case attributes
            case description
            case recommendation
            case scopes
            case title
        }
    }

    public struct ExclusionPreview: AWSDecodableShape {
        /// The system-defined attributes for the exclusion preview.
        public let attributes: [Attribute]?
        /// The description of the exclusion preview.
        public let description: String
        /// The recommendation for the exclusion preview.
        public let recommendation: String
        /// The AWS resources for which the exclusion preview pertains.
        public let scopes: [Scope]
        /// The name of the exclusion preview.
        public let title: String

        public init(attributes: [Attribute]? = nil, description: String, recommendation: String, scopes: [Scope], title: String) {
            self.attributes = attributes
            self.description = description
            self.recommendation = recommendation
            self.scopes = scopes
            self.title = title
        }

        private enum CodingKeys: String, CodingKey {
            case attributes
            case description
            case recommendation
            case scopes
            case title
        }
    }

    public struct FailedItemDetails: AWSDecodableShape {
        /// The status code of a failed item.
        public let failureCode: FailedItemErrorCode
        /// Indicates whether you can immediately retry a request for this item for a specified resource.
        public let retryable: Bool

        public init(failureCode: FailedItemErrorCode, retryable: Bool) {
            self.failureCode = failureCode
            self.retryable = retryable
        }

        private enum CodingKeys: String, CodingKey {
            case failureCode
            case retryable
        }
    }

    public struct Finding: AWSDecodableShape {
        /// The ARN that specifies the finding.
        public let arn: String
        /// A collection of attributes of the host from which the finding is generated.
        public let assetAttributes: AssetAttributes?
        /// The type of the host from which the finding is generated.
        public let assetType: AssetType?
        /// The system-defined attributes for the finding.
        public let attributes: [Attribute]
        /// This data element is currently not used.
        public let confidence: Int?
        /// The time when the finding was generated.
        public let createdAt: Date
        /// The description of the finding.
        public let description: String?
        /// The ID of the finding.
        public let id: String?
        /// This data element is currently not used.
        public let indicatorOfCompromise: Bool?
        /// The numeric value of the finding severity.
        public let numericSeverity: Double?
        /// The recommendation for the finding.
        public let recommendation: String?
        /// The schema version of this data type.
        public let schemaVersion: Int?
        /// The data element is set to "Inspector".
        public let service: String?
        /// This data type is used in the Finding data type.
        public let serviceAttributes: InspectorServiceAttributes?
        /// The finding severity. Values can be set to High, Medium, Low, and Informational.
        public let severity: Severity?
        /// The name of the finding.
        public let title: String?
        /// The time when AddAttributesToFindings is called.
        public let updatedAt: Date
        /// The user-defined attributes that are assigned to the finding.
        public let userAttributes: [Attribute]

        public init(arn: String, assetAttributes: AssetAttributes? = nil, assetType: AssetType? = nil, attributes: [Attribute], confidence: Int? = nil, createdAt: Date, description: String? = nil, id: String? = nil, indicatorOfCompromise: Bool? = nil, numericSeverity: Double? = nil, recommendation: String? = nil, schemaVersion: Int? = nil, service: String? = nil, serviceAttributes: InspectorServiceAttributes? = nil, severity: Severity? = nil, title: String? = nil, updatedAt: Date, userAttributes: [Attribute]) {
            self.arn = arn
            self.assetAttributes = assetAttributes
            self.assetType = assetType
            self.attributes = attributes
            self.confidence = confidence
            self.createdAt = createdAt
            self.description = description
            self.id = id
            self.indicatorOfCompromise = indicatorOfCompromise
            self.numericSeverity = numericSeverity
            self.recommendation = recommendation
            self.schemaVersion = schemaVersion
            self.service = service
            self.serviceAttributes = serviceAttributes
            self.severity = severity
            self.title = title
            self.updatedAt = updatedAt
            self.userAttributes = userAttributes
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case assetAttributes
            case assetType
            case attributes
            case confidence
            case createdAt
            case description
            case id
            case indicatorOfCompromise
            case numericSeverity
            case recommendation
            case schemaVersion
            case service
            case serviceAttributes
            case severity
            case title
            case updatedAt
            case userAttributes
        }
    }

    public struct FindingFilter: AWSEncodableShape {
        /// For a record to match a filter, one of the values that is specified for this data type property must be the exact match of the value of the agentId property of the Finding data type.
        public let agentIds: [String]?
        /// For a record to match a filter, the list of values that are specified for this data type property must be contained in the list of values of the attributes property of the Finding data type.
        public let attributes: [Attribute]?
        /// For a record to match a filter, one of the values that is specified for this data type property must be the exact match of the value of the autoScalingGroup property of the Finding data type.
        public let autoScalingGroups: [String]?
        /// The time range during which the finding is generated.
        public let creationTimeRange: TimestampRange?
        /// For a record to match a filter, one of the values that is specified for this data type property must be the exact match of the value of the ruleName property of the Finding data type.
        public let ruleNames: [String]?
        /// For a record to match a filter, one of the values that is specified for this data type property must be the exact match of the value of the rulesPackageArn property of the Finding data type.
        public let rulesPackageArns: [String]?
        /// For a record to match a filter, one of the values that is specified for this data type property must be the exact match of the value of the severity property of the Finding data type.
        public let severities: [Severity]?
        /// For a record to match a filter, the value that is specified for this data type property must be contained in the list of values of the userAttributes property of the Finding data type.
        public let userAttributes: [Attribute]?

        public init(agentIds: [String]? = nil, attributes: [Attribute]? = nil, autoScalingGroups: [String]? = nil, creationTimeRange: TimestampRange? = nil, ruleNames: [String]? = nil, rulesPackageArns: [String]? = nil, severities: [Severity]? = nil, userAttributes: [Attribute]? = nil) {
            self.agentIds = agentIds
            self.attributes = attributes
            self.autoScalingGroups = autoScalingGroups
            self.creationTimeRange = creationTimeRange
            self.ruleNames = ruleNames
            self.rulesPackageArns = rulesPackageArns
            self.severities = severities
            self.userAttributes = userAttributes
        }

        public func validate(name: String) throws {
            try self.agentIds?.forEach {
                try validate($0, name: "agentIds[]", parent: name, max: 128)
                try validate($0, name: "agentIds[]", parent: name, min: 1)
            }
            try self.validate(self.agentIds, name: "agentIds", parent: name, max: 99)
            try self.attributes?.forEach {
                try $0.validate(name: "\(name).attributes[]")
            }
            try self.validate(self.attributes, name: "attributes", parent: name, max: 50)
            try self.autoScalingGroups?.forEach {
                try validate($0, name: "autoScalingGroups[]", parent: name, max: 256)
                try validate($0, name: "autoScalingGroups[]", parent: name, min: 1)
            }
            try self.validate(self.autoScalingGroups, name: "autoScalingGroups", parent: name, max: 20)
            try self.ruleNames?.forEach {
                try validate($0, name: "ruleNames[]", parent: name, max: 1000)
            }
            try self.validate(self.ruleNames, name: "ruleNames", parent: name, max: 50)
            try self.rulesPackageArns?.forEach {
                try validate($0, name: "rulesPackageArns[]", parent: name, max: 300)
                try validate($0, name: "rulesPackageArns[]", parent: name, min: 1)
            }
            try self.validate(self.rulesPackageArns, name: "rulesPackageArns", parent: name, max: 50)
            try self.validate(self.severities, name: "severities", parent: name, max: 50)
            try self.userAttributes?.forEach {
                try $0.validate(name: "\(name).userAttributes[]")
            }
            try self.validate(self.userAttributes, name: "userAttributes", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case agentIds
            case attributes
            case autoScalingGroups
            case creationTimeRange
            case ruleNames
            case rulesPackageArns
            case severities
            case userAttributes
        }
    }

    public struct GetAssessmentReportRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment run for which you want to generate a report.
        public let assessmentRunArn: String
        /// Specifies the file format (html or pdf) of the assessment report that you want to generate.
        public let reportFileFormat: ReportFileFormat
        /// Specifies the type of the assessment report that you want to generate. There are two types of assessment reports: a finding report and a full report. For more information, see Assessment Reports.
        public let reportType: ReportType

        public init(assessmentRunArn: String, reportFileFormat: ReportFileFormat, reportType: ReportType) {
            self.assessmentRunArn = assessmentRunArn
            self.reportFileFormat = reportFileFormat
            self.reportType = reportType
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
            case reportFileFormat
            case reportType
        }
    }

    public struct GetAssessmentReportResponse: AWSDecodableShape {
        /// Specifies the status of the request to generate an assessment report.
        public let status: ReportStatus
        /// Specifies the URL where you can find the generated assessment report. This parameter is only returned if the report is successfully generated.
        public let url: String?

        public init(status: ReportStatus, url: String? = nil) {
            self.status = status
            self.url = url
        }

        private enum CodingKeys: String, CodingKey {
            case status
            case url
        }
    }

    public struct GetExclusionsPreviewRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment template for which the exclusions preview was requested.
        public let assessmentTemplateArn: String
        /// The locale into which you want to translate the exclusion's title, description, and recommendation.
        public let locale: Locale?
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 100. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the GetExclusionsPreviewRequest action. Subsequent calls to the action fill nextToken in the request with the value of nextToken from the previous response to continue listing data.
        public let nextToken: String?
        /// The unique identifier associated of the exclusions preview.
        public let previewToken: String

        public init(assessmentTemplateArn: String, locale: Locale? = nil, maxResults: Int? = nil, nextToken: String? = nil, previewToken: String) {
            self.assessmentTemplateArn = assessmentTemplateArn
            self.locale = locale
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.previewToken = previewToken
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, max: 300)
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.previewToken, name: "previewToken", parent: name, pattern: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArn
            case locale
            case maxResults
            case nextToken
            case previewToken
        }
    }

    public struct GetExclusionsPreviewResponse: AWSDecodableShape {
        /// Information about the exclusions included in the preview.
        public let exclusionPreviews: [ExclusionPreview]?
        /// When a response is generated, if there is more data to be listed, this parameters is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?
        /// Specifies the status of the request to generate an exclusions preview.
        public let previewStatus: PreviewStatus

        public init(exclusionPreviews: [ExclusionPreview]? = nil, nextToken: String? = nil, previewStatus: PreviewStatus) {
            self.exclusionPreviews = exclusionPreviews
            self.nextToken = nextToken
            self.previewStatus = previewStatus
        }

        private enum CodingKeys: String, CodingKey {
            case exclusionPreviews
            case nextToken
            case previewStatus
        }
    }

    public struct GetTelemetryMetadataRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment run that has the telemetry data that you want to obtain.
        public let assessmentRunArn: String

        public init(assessmentRunArn: String) {
            self.assessmentRunArn = assessmentRunArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
        }
    }

    public struct GetTelemetryMetadataResponse: AWSDecodableShape {
        /// Telemetry details.
        public let telemetryMetadata: [TelemetryMetadata]

        public init(telemetryMetadata: [TelemetryMetadata]) {
            self.telemetryMetadata = telemetryMetadata
        }

        private enum CodingKeys: String, CodingKey {
            case telemetryMetadata
        }
    }

    public struct InspectorServiceAttributes: AWSDecodableShape {
        /// The ARN of the assessment run during which the finding is generated.
        public let assessmentRunArn: String?
        /// The ARN of the rules package that is used to generate the finding.
        public let rulesPackageArn: String?
        /// The schema version of this data type.
        public let schemaVersion: Int

        public init(assessmentRunArn: String? = nil, rulesPackageArn: String? = nil, schemaVersion: Int) {
            self.assessmentRunArn = assessmentRunArn
            self.rulesPackageArn = rulesPackageArn
            self.schemaVersion = schemaVersion
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
            case rulesPackageArn
            case schemaVersion
        }
    }

    public struct ListAssessmentRunAgentsRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment run whose agents you want to list.
        public let assessmentRunArn: String
        /// You can use this parameter to specify a subset of data to be included in the action's response. For a record to match a filter, all specified filter attributes must match. When multiple values are specified for a filter attribute, any of the values can match.
        public let filter: AgentFilter?
        /// You can use this parameter to indicate the maximum number of items that you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListAssessmentRunAgents action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(assessmentRunArn: String, filter: AgentFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.assessmentRunArn = assessmentRunArn
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
            case filter
            case maxResults
            case nextToken
        }
    }

    public struct ListAssessmentRunAgentsResponse: AWSDecodableShape {
        /// A list of ARNs that specifies the agents returned by the action.
        public let assessmentRunAgents: [AssessmentRunAgent]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(assessmentRunAgents: [AssessmentRunAgent], nextToken: String? = nil) {
            self.assessmentRunAgents = assessmentRunAgents
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunAgents
            case nextToken
        }
    }

    public struct ListAssessmentRunsRequest: AWSEncodableShape {
        /// The ARNs that specify the assessment templates whose assessment runs you want to list.
        public let assessmentTemplateArns: [String]?
        /// You can use this parameter to specify a subset of data to be included in the action's response. For a record to match a filter, all specified filter attributes must match. When multiple values are specified for a filter attribute, any of the values can match.
        public let filter: AssessmentRunFilter?
        /// You can use this parameter to indicate the maximum number of items that you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListAssessmentRuns action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(assessmentTemplateArns: [String]? = nil, filter: AssessmentRunFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.assessmentTemplateArns = assessmentTemplateArns
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.assessmentTemplateArns?.forEach {
                try validate($0, name: "assessmentTemplateArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentTemplateArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentTemplateArns, name: "assessmentTemplateArns", parent: name, max: 50)
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArns
            case filter
            case maxResults
            case nextToken
        }
    }

    public struct ListAssessmentRunsResponse: AWSDecodableShape {
        /// A list of ARNs that specifies the assessment runs that are returned by the action.
        public let assessmentRunArns: [String]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(assessmentRunArns: [String], nextToken: String? = nil) {
            self.assessmentRunArns = assessmentRunArns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArns
            case nextToken
        }
    }

    public struct ListAssessmentTargetsRequest: AWSEncodableShape {
        /// You can use this parameter to specify a subset of data to be included in the action's response. For a record to match a filter, all specified filter attributes must match. When multiple values are specified for a filter attribute, any of the values can match.
        public let filter: AssessmentTargetFilter?
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListAssessmentTargets action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(filter: AssessmentTargetFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case filter
            case maxResults
            case nextToken
        }
    }

    public struct ListAssessmentTargetsResponse: AWSDecodableShape {
        /// A list of ARNs that specifies the assessment targets that are returned by the action.
        public let assessmentTargetArns: [String]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(assessmentTargetArns: [String], nextToken: String? = nil) {
            self.assessmentTargetArns = assessmentTargetArns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArns
            case nextToken
        }
    }

    public struct ListAssessmentTemplatesRequest: AWSEncodableShape {
        /// A list of ARNs that specifies the assessment targets whose assessment templates you want to list.
        public let assessmentTargetArns: [String]?
        /// You can use this parameter to specify a subset of data to be included in the action's response. For a record to match a filter, all specified filter attributes must match. When multiple values are specified for a filter attribute, any of the values can match.
        public let filter: AssessmentTemplateFilter?
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListAssessmentTemplates action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(assessmentTargetArns: [String]? = nil, filter: AssessmentTemplateFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.assessmentTargetArns = assessmentTargetArns
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.assessmentTargetArns?.forEach {
                try validate($0, name: "assessmentTargetArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentTargetArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentTargetArns, name: "assessmentTargetArns", parent: name, max: 50)
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArns
            case filter
            case maxResults
            case nextToken
        }
    }

    public struct ListAssessmentTemplatesResponse: AWSDecodableShape {
        /// A list of ARNs that specifies the assessment templates returned by the action.
        public let assessmentTemplateArns: [String]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(assessmentTemplateArns: [String], nextToken: String? = nil) {
            self.assessmentTemplateArns = assessmentTemplateArns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTemplateArns
            case nextToken
        }
    }

    public struct ListEventSubscriptionsRequest: AWSEncodableShape {
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListEventSubscriptions action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?
        /// The ARN of the assessment template for which you want to list the existing event subscriptions.
        public let resourceArn: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceArn: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 300)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults
            case nextToken
            case resourceArn
        }
    }

    public struct ListEventSubscriptionsResponse: AWSDecodableShape {
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?
        /// Details of the returned event subscriptions.
        public let subscriptions: [Subscription]

        public init(nextToken: String? = nil, subscriptions: [Subscription]) {
            self.nextToken = nextToken
            self.subscriptions = subscriptions
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case subscriptions
        }
    }

    public struct ListExclusionsRequest: AWSEncodableShape {
        /// The ARN of the assessment run that generated the exclusions that you want to list.
        public let assessmentRunArn: String
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 100. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListExclusionsRequest action. Subsequent calls to the action fill nextToken in the request with the value of nextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(assessmentRunArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.assessmentRunArn = assessmentRunArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
            case maxResults
            case nextToken
        }
    }

    public struct ListExclusionsResponse: AWSDecodableShape {
        /// A list of exclusions' ARNs returned by the action.
        public let exclusionArns: [String]
        /// When a response is generated, if there is more data to be listed, this parameters is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(exclusionArns: [String], nextToken: String? = nil) {
            self.exclusionArns = exclusionArns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case exclusionArns
            case nextToken
        }
    }

    public struct ListFindingsRequest: AWSEncodableShape {
        /// The ARNs of the assessment runs that generate the findings that you want to list.
        public let assessmentRunArns: [String]?
        /// You can use this parameter to specify a subset of data to be included in the action's response. For a record to match a filter, all specified filter attributes must match. When multiple values are specified for a filter attribute, any of the values can match.
        public let filter: FindingFilter?
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListFindings action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(assessmentRunArns: [String]? = nil, filter: FindingFilter? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.assessmentRunArns = assessmentRunArns
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.assessmentRunArns?.forEach {
                try validate($0, name: "assessmentRunArns[]", parent: name, max: 300)
                try validate($0, name: "assessmentRunArns[]", parent: name, min: 1)
            }
            try self.validate(self.assessmentRunArns, name: "assessmentRunArns", parent: name, max: 50)
            try self.filter?.validate(name: "\(name).filter")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArns
            case filter
            case maxResults
            case nextToken
        }
    }

    public struct ListFindingsResponse: AWSDecodableShape {
        /// A list of ARNs that specifies the findings returned by the action.
        public let findingArns: [String]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(findingArns: [String], nextToken: String? = nil) {
            self.findingArns = findingArns
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case findingArns
            case nextToken
        }
    }

    public struct ListRulesPackagesRequest: AWSEncodableShape {
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the ListRulesPackages action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults
            case nextToken
        }
    }

    public struct ListRulesPackagesResponse: AWSDecodableShape {
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?
        /// The list of ARNs that specifies the rules packages returned by the action.
        public let rulesPackageArns: [String]

        public init(nextToken: String? = nil, rulesPackageArns: [String]) {
            self.nextToken = nextToken
            self.rulesPackageArns = rulesPackageArns
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken
            case rulesPackageArns
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN that specifies the assessment template whose tags you want to list.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 300)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// A collection of key and value pairs.
        public let tags: [Tag]

        public init(tags: [Tag]) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct NetworkInterface: AWSDecodableShape {
        /// The IP addresses associated with the network interface.
        public let ipv6Addresses: [String]?
        /// The ID of the network interface.
        public let networkInterfaceId: String?
        /// The name of a private DNS associated with the network interface.
        public let privateDnsName: String?
        /// The private IP address associated with the network interface.
        public let privateIpAddress: String?
        /// A list of the private IP addresses associated with the network interface. Includes the privateDnsName and privateIpAddress.
        public let privateIpAddresses: [PrivateIp]?
        /// The name of a public DNS associated with the network interface.
        public let publicDnsName: String?
        /// The public IP address from which the network interface is reachable.
        public let publicIp: String?
        /// A list of the security groups associated with the network interface. Includes the groupId and groupName.
        public let securityGroups: [SecurityGroup]?
        /// The ID of a subnet associated with the network interface.
        public let subnetId: String?
        /// The ID of a VPC associated with the network interface.
        public let vpcId: String?

        public init(ipv6Addresses: [String]? = nil, networkInterfaceId: String? = nil, privateDnsName: String? = nil, privateIpAddress: String? = nil, privateIpAddresses: [PrivateIp]? = nil, publicDnsName: String? = nil, publicIp: String? = nil, securityGroups: [SecurityGroup]? = nil, subnetId: String? = nil, vpcId: String? = nil) {
            self.ipv6Addresses = ipv6Addresses
            self.networkInterfaceId = networkInterfaceId
            self.privateDnsName = privateDnsName
            self.privateIpAddress = privateIpAddress
            self.privateIpAddresses = privateIpAddresses
            self.publicDnsName = publicDnsName
            self.publicIp = publicIp
            self.securityGroups = securityGroups
            self.subnetId = subnetId
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case ipv6Addresses
            case networkInterfaceId
            case privateDnsName
            case privateIpAddress
            case privateIpAddresses
            case publicDnsName
            case publicIp
            case securityGroups
            case subnetId
            case vpcId
        }
    }

    public struct PreviewAgentsRequest: AWSEncodableShape {
        /// You can use this parameter to indicate the maximum number of items you want in the response. The default value is 10. The maximum value is 500.
        public let maxResults: Int?
        /// You can use this parameter when paginating results. Set the value of this parameter to null on your first call to the PreviewAgents action. Subsequent calls to the action fill nextToken in the request with the value of NextToken from the previous response to continue listing data.
        public let nextToken: String?
        /// The ARN of the assessment target whose agents you want to preview.
        public let previewAgentsArn: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, previewAgentsArn: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.previewAgentsArn = previewAgentsArn
        }

        public func validate(name: String) throws {
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 300)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.previewAgentsArn, name: "previewAgentsArn", parent: name, max: 300)
            try self.validate(self.previewAgentsArn, name: "previewAgentsArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults
            case nextToken
            case previewAgentsArn
        }
    }

    public struct PreviewAgentsResponse: AWSDecodableShape {
        /// The resulting list of agents.
        public let agentPreviews: [AgentPreview]
        ///  When a response is generated, if there is more data to be listed, this parameter is present in the response and contains the value to use for the nextToken parameter in a subsequent pagination request. If there is no more data to be listed, this parameter is set to null.
        public let nextToken: String?

        public init(agentPreviews: [AgentPreview], nextToken: String? = nil) {
            self.agentPreviews = agentPreviews
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case agentPreviews
            case nextToken
        }
    }

    public struct PrivateIp: AWSDecodableShape {
        /// The DNS name of the private IP address.
        public let privateDnsName: String?
        /// The full IP address of the network inteface.
        public let privateIpAddress: String?

        public init(privateDnsName: String? = nil, privateIpAddress: String? = nil) {
            self.privateDnsName = privateDnsName
            self.privateIpAddress = privateIpAddress
        }

        private enum CodingKeys: String, CodingKey {
            case privateDnsName
            case privateIpAddress
        }
    }

    public struct RegisterCrossAccountAccessRoleRequest: AWSEncodableShape {
        /// The ARN of the IAM role that grants Amazon Inspector access to AWS Services needed to perform security assessments.
        public let roleArn: String

        public init(roleArn: String) {
            self.roleArn = roleArn
        }

        public func validate(name: String) throws {
            try self.validate(self.roleArn, name: "roleArn", parent: name, max: 300)
            try self.validate(self.roleArn, name: "roleArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case roleArn
        }
    }

    public struct RemoveAttributesFromFindingsRequest: AWSEncodableShape {
        /// The array of attribute keys that you want to remove from specified findings.
        public let attributeKeys: [String]
        /// The ARNs that specify the findings that you want to remove attributes from.
        public let findingArns: [String]

        public init(attributeKeys: [String], findingArns: [String]) {
            self.attributeKeys = attributeKeys
            self.findingArns = findingArns
        }

        public func validate(name: String) throws {
            try self.attributeKeys.forEach {
                try validate($0, name: "attributeKeys[]", parent: name, max: 128)
                try validate($0, name: "attributeKeys[]", parent: name, min: 1)
            }
            try self.validate(self.attributeKeys, name: "attributeKeys", parent: name, max: 10)
            try self.findingArns.forEach {
                try validate($0, name: "findingArns[]", parent: name, max: 300)
                try validate($0, name: "findingArns[]", parent: name, min: 1)
            }
            try self.validate(self.findingArns, name: "findingArns", parent: name, max: 10)
            try self.validate(self.findingArns, name: "findingArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case attributeKeys
            case findingArns
        }
    }

    public struct RemoveAttributesFromFindingsResponse: AWSDecodableShape {
        /// Attributes details that cannot be described. An error code is provided for each failed item.
        public let failedItems: [String: FailedItemDetails]

        public init(failedItems: [String: FailedItemDetails]) {
            self.failedItems = failedItems
        }

        private enum CodingKeys: String, CodingKey {
            case failedItems
        }
    }

    public struct ResourceGroup: AWSDecodableShape {
        /// The ARN of the resource group.
        public let arn: String
        /// The time at which resource group is created.
        public let createdAt: Date
        /// The tags (key and value pairs) of the resource group. This data type property is used in the CreateResourceGroup action.
        public let tags: [ResourceGroupTag]

        public init(arn: String, createdAt: Date, tags: [ResourceGroupTag]) {
            self.arn = arn
            self.createdAt = createdAt
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdAt
            case tags
        }
    }

    public struct ResourceGroupTag: AWSEncodableShape & AWSDecodableShape {
        /// A tag key.
        public let key: String
        /// The value assigned to a tag key.
        public let value: String?

        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct RulesPackage: AWSDecodableShape {
        /// The ARN of the rules package.
        public let arn: String
        /// The description of the rules package.
        public let description: String?
        /// The name of the rules package.
        public let name: String
        /// The provider of the rules package.
        public let provider: String
        /// The version ID of the rules package.
        public let version: String

        public init(arn: String, description: String? = nil, name: String, provider: String, version: String) {
            self.arn = arn
            self.description = description
            self.name = name
            self.provider = provider
            self.version = version
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case description
            case name
            case provider
            case version
        }
    }

    public struct Scope: AWSDecodableShape {
        /// The type of the scope.
        public let key: ScopeType?
        /// The resource identifier for the specified scope type.
        public let value: String?

        public init(key: ScopeType? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct SecurityGroup: AWSDecodableShape {
        /// The ID of the security group.
        public let groupId: String?
        /// The name of the security group.
        public let groupName: String?

        public init(groupId: String? = nil, groupName: String? = nil) {
            self.groupId = groupId
            self.groupName = groupName
        }

        private enum CodingKeys: String, CodingKey {
            case groupId
            case groupName
        }
    }

    public struct SetTagsForResourceRequest: AWSEncodableShape {
        /// The ARN of the assessment template that you want to set tags to.
        public let resourceArn: String
        /// A collection of key and value pairs that you want to set to the assessment template.
        public let tags: [Tag]?

        public init(resourceArn: String, tags: [Tag]? = nil) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 300)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 10)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn
            case tags
        }
    }

    public struct StartAssessmentRunRequest: AWSEncodableShape {
        /// You can specify the name for the assessment run. The name must be unique for the assessment template whose ARN is used to start the assessment run.
        public let assessmentRunName: String?
        /// The ARN of the assessment template of the assessment run that you want to start.
        public let assessmentTemplateArn: String

        public init(assessmentRunName: String? = nil, assessmentTemplateArn: String) {
            self.assessmentRunName = assessmentRunName
            self.assessmentTemplateArn = assessmentTemplateArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunName, name: "assessmentRunName", parent: name, max: 140)
            try self.validate(self.assessmentRunName, name: "assessmentRunName", parent: name, min: 1)
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, max: 300)
            try self.validate(self.assessmentTemplateArn, name: "assessmentTemplateArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunName
            case assessmentTemplateArn
        }
    }

    public struct StartAssessmentRunResponse: AWSDecodableShape {
        /// The ARN of the assessment run that has been started.
        public let assessmentRunArn: String

        public init(assessmentRunArn: String) {
            self.assessmentRunArn = assessmentRunArn
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
        }
    }

    public struct StopAssessmentRunRequest: AWSEncodableShape {
        /// The ARN of the assessment run that you want to stop.
        public let assessmentRunArn: String
        /// An input option that can be set to either START_EVALUATION or SKIP_EVALUATION. START_EVALUATION (the default value), stops the AWS agent from collecting data and begins the results evaluation and the findings generation process. SKIP_EVALUATION cancels the assessment run immediately, after which no findings are generated.
        public let stopAction: StopAction?

        public init(assessmentRunArn: String, stopAction: StopAction? = nil) {
            self.assessmentRunArn = assessmentRunArn
            self.stopAction = stopAction
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, max: 300)
            try self.validate(self.assessmentRunArn, name: "assessmentRunArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentRunArn
            case stopAction
        }
    }

    public struct SubscribeToEventRequest: AWSEncodableShape {
        /// The event for which you want to receive SNS notifications.
        public let event: InspectorEvent
        /// The ARN of the assessment template that is used during the event for which you want to receive SNS notifications.
        public let resourceArn: String
        /// The ARN of the SNS topic to which the SNS notifications are sent.
        public let topicArn: String

        public init(event: InspectorEvent, resourceArn: String, topicArn: String) {
            self.event = event
            self.resourceArn = resourceArn
            self.topicArn = topicArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 300)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.topicArn, name: "topicArn", parent: name, max: 300)
            try self.validate(self.topicArn, name: "topicArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case event
            case resourceArn
            case topicArn
        }
    }

    public struct Subscription: AWSDecodableShape {
        /// The list of existing event subscriptions.
        public let eventSubscriptions: [EventSubscription]
        /// The ARN of the assessment template that is used during the event for which the SNS notification is sent.
        public let resourceArn: String
        /// The ARN of the Amazon Simple Notification Service (SNS) topic to which the SNS notifications are sent.
        public let topicArn: String

        public init(eventSubscriptions: [EventSubscription], resourceArn: String, topicArn: String) {
            self.eventSubscriptions = eventSubscriptions
            self.resourceArn = resourceArn
            self.topicArn = topicArn
        }

        private enum CodingKeys: String, CodingKey {
            case eventSubscriptions
            case resourceArn
            case topicArn
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// A tag key.
        public let key: String
        /// A value assigned to a tag key.
        public let value: String?

        public init(key: String, value: String? = nil) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct TelemetryMetadata: AWSDecodableShape {
        /// The count of messages that the agent sends to the Amazon Inspector service.
        public let count: Int64
        /// The data size of messages that the agent sends to the Amazon Inspector service.
        public let dataSize: Int64?
        /// A specific type of behavioral data that is collected by the agent.
        public let messageType: String

        public init(count: Int64, dataSize: Int64? = nil, messageType: String) {
            self.count = count
            self.dataSize = dataSize
            self.messageType = messageType
        }

        private enum CodingKeys: String, CodingKey {
            case count
            case dataSize
            case messageType
        }
    }

    public struct TimestampRange: AWSEncodableShape {
        /// The minimum value of the timestamp range.
        public let beginDate: Date?
        /// The maximum value of the timestamp range.
        public let endDate: Date?

        public init(beginDate: Date? = nil, endDate: Date? = nil) {
            self.beginDate = beginDate
            self.endDate = endDate
        }

        private enum CodingKeys: String, CodingKey {
            case beginDate
            case endDate
        }
    }

    public struct UnsubscribeFromEventRequest: AWSEncodableShape {
        /// The event for which you want to stop receiving SNS notifications.
        public let event: InspectorEvent
        /// The ARN of the assessment template that is used during the event for which you want to stop receiving SNS notifications.
        public let resourceArn: String
        /// The ARN of the SNS topic to which SNS notifications are sent.
        public let topicArn: String

        public init(event: InspectorEvent, resourceArn: String, topicArn: String) {
            self.event = event
            self.resourceArn = resourceArn
            self.topicArn = topicArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 300)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.topicArn, name: "topicArn", parent: name, max: 300)
            try self.validate(self.topicArn, name: "topicArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case event
            case resourceArn
            case topicArn
        }
    }

    public struct UpdateAssessmentTargetRequest: AWSEncodableShape {
        /// The ARN of the assessment target that you want to update.
        public let assessmentTargetArn: String
        /// The name of the assessment target that you want to update.
        public let assessmentTargetName: String
        /// The ARN of the resource group that is used to specify the new resource group to associate with the assessment target.
        public let resourceGroupArn: String?

        public init(assessmentTargetArn: String, assessmentTargetName: String, resourceGroupArn: String? = nil) {
            self.assessmentTargetArn = assessmentTargetArn
            self.assessmentTargetName = assessmentTargetName
            self.resourceGroupArn = resourceGroupArn
        }

        public func validate(name: String) throws {
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, max: 300)
            try self.validate(self.assessmentTargetArn, name: "assessmentTargetArn", parent: name, min: 1)
            try self.validate(self.assessmentTargetName, name: "assessmentTargetName", parent: name, max: 140)
            try self.validate(self.assessmentTargetName, name: "assessmentTargetName", parent: name, min: 1)
            try self.validate(self.resourceGroupArn, name: "resourceGroupArn", parent: name, max: 300)
            try self.validate(self.resourceGroupArn, name: "resourceGroupArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case assessmentTargetArn
            case assessmentTargetName
            case resourceGroupArn
        }
    }
}

// MARK: - Errors

/// Error enum for Inspector
public struct InspectorErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case agentsAlreadyRunningAssessmentException = "AgentsAlreadyRunningAssessmentException"
        case assessmentRunInProgressException = "AssessmentRunInProgressException"
        case internalException = "InternalException"
        case invalidCrossAccountRoleException = "InvalidCrossAccountRoleException"
        case invalidInputException = "InvalidInputException"
        case limitExceededException = "LimitExceededException"
        case noSuchEntityException = "NoSuchEntityException"
        case previewGenerationInProgressException = "PreviewGenerationInProgressException"
        case serviceTemporarilyUnavailableException = "ServiceTemporarilyUnavailableException"
        case unsupportedFeatureException = "UnsupportedFeatureException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Inspector
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have required permissions to access the requested resource.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// You started an assessment run, but one of the instances is already participating in another assessment run.
    public static var agentsAlreadyRunningAssessmentException: Self { .init(.agentsAlreadyRunningAssessmentException) }
    /// You cannot perform a specified action if an assessment run is currently in progress.
    public static var assessmentRunInProgressException: Self { .init(.assessmentRunInProgressException) }
    /// Internal server error.
    public static var internalException: Self { .init(.internalException) }
    /// Amazon Inspector cannot assume the cross-account role that it needs to list your EC2 instances during the assessment run.
    public static var invalidCrossAccountRoleException: Self { .init(.invalidCrossAccountRoleException) }
    /// The request was rejected because an invalid or out-of-range value was supplied for an input parameter.
    public static var invalidInputException: Self { .init(.invalidInputException) }
    /// The request was rejected because it attempted to create resources beyond the current AWS account limits. The error code describes the limit exceeded.
    public static var limitExceededException: Self { .init(.limitExceededException) }
    /// The request was rejected because it referenced an entity that does not exist. The error code describes the entity.
    public static var noSuchEntityException: Self { .init(.noSuchEntityException) }
    /// The request is rejected. The specified assessment template is currently generating an exclusions preview.
    public static var previewGenerationInProgressException: Self { .init(.previewGenerationInProgressException) }
    /// The serice is temporary unavailable.
    public static var serviceTemporarilyUnavailableException: Self { .init(.serviceTemporarilyUnavailableException) }
    /// Used by the GetAssessmentReport API. The request was rejected because you tried to generate a report for an assessment run that existed before reporting was supported in Amazon Inspector. You can only generate reports for assessment runs that took place or will take place after generating reports in Amazon Inspector became available.
    public static var unsupportedFeatureException: Self { .init(.unsupportedFeatureException) }
}

extension InspectorErrorType: Equatable {
    public static func == (lhs: InspectorErrorType, rhs: InspectorErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension InspectorErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
